// NSQ队列消息
// 此模块依赖xlog模块，所以使用时请注意使用 `xlog.Regedit()` 来注册日志配置
package xnsq

import (
	"sync"
	"time"
)

// 队列配置
type NsqFuncConf struct {
	Key           string                   // 下标标识
	Name          string                   // 队列任务名称
	Desc          string                   // 队列任务描述
	RunSuccessNum uint                     // 成功运行次数
	RunErrorNum   uint                     // 失败运行次数
	PreviousError string                   // 上次运行失败的原因
	PreviousTime  string                   // 上次运行时间
	TimeSlot      time.Duration            // 时间段内
	RunMax        uint                     // 允许执行的数量，即到此数量且时间超出后就进行归零
	runNum        uint                     // 该时间段内已运行次数
	runZeroTime   time.Time                // 上次归零时间
	Func          func(param []byte) error `json:"-"` // 执行的函数操作
}

// 队列消息路由
// 此路由使用go作为客户端进行监听/注入，所以此处是需要在main程序中进行携程运行的
var nsq_lock sync.RWMutex

// 队列运行配置信息
var nsq_runtime map[string]*NsqFuncConf = map[string]*NsqFuncConf{}

// NSQ的message消息结构，用于json解构及参数传递
type NSQ struct {
	Func    string `json:"func"`     // 调用方法
	Time    string `json:"time"`     // 发送时间
	Param   any    `json:"param"`    // 传入参数
	RunTime string `json:"run_time"` // 期望运行时间，若此值不为空则表示再次延时
}

// 配置项信息
type Config struct {
	Set            string // 写入队列的nsqd服务域名端口，一般为127.0.0.1:4150
	SetTopic       string // 写入队列的topic名称
	Get            string // 读取队列的nsqlookupd域名端口，一般为127.0.0.1:4161，空表示不监听此服务
	GetTopic       string // 读取队列的get_topic服务
	GetChannel     string // 读取队列的get_channel服务
	GetMaxInFlight int    // 最大并发消费数配置，建议配置为nsqd服务的倍数，默认为1
	MaxAttempts    uint16 // 错误最大重试次数
}

// 默认配置
var _default Config = Config{
	SetTopic:       "golang-xnsq",
	GetTopic:       "golang-xnsq",
	GetChannel:     "xnsq-channel",
	GetMaxInFlight: 1,
	MaxAttempts:    6,
}

// 注入配置项
func Regedit(c *Config) {
	if c == nil {
		return
	}
	if c.Set != "" {
		_default.Set = c.Set
	}
	if c.SetTopic != "" {
		_default.SetTopic = c.SetTopic
	}
	if c.Get != "" {
		_default.Get = c.Get
	}
	if c.GetTopic != "" {
		_default.GetTopic = c.GetTopic
	}
	if c.GetChannel != "" {
		_default.GetChannel = c.GetChannel
	}
	if c.GetMaxInFlight > 0 {
		_default.GetMaxInFlight = c.GetMaxInFlight
	}
	if c.MaxAttempts > 0 {
		_default.MaxAttempts = c.MaxAttempts
	}
	// 添加默认队列支持
	AddNsqConf("xnsq.https.quest", &NsqFuncConf{
		Name: "使用队列直接控制请求其他网址",
		Desc: "传入队列参数URL、Method、Param等以后，直接排队/按时请求该网址，并控制返回日志记录到xlog.Crit中",
		Func: httpsQuest,
	})
}
